﻿using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.IO;
using WMPLib;

namespace WebSiteUpdateChecker
{
    public partial class OptionForm : Form
    {
        /// <summary>バインドされたコントロール一覧。</summary>
        private Control[] BindedControls;
        /// <summary>MediaPlayerオブジェクト。</summary>
        WindowsMediaPlayer mediaPlayer;



        /// <summary>
        /// コンストラクタ。
        /// </summary>
        public OptionForm()
        {
            InitializeComponent();

            this.BindedControls = GetBindedControls(this);
            this.mediaPlayer = new WindowsMediaPlayer();
        }

        /// <summary>
        /// 全てのコントロールを取得する。
        /// </summary>
        /// <param name="baseControl">コントロールを取得するコントロール。</param>
        /// <returns>コントロールの一覧。</returns>
        private Control[] GetBindedControls(Control baseControl)
        {
            List<Control> controlList = new List<Control>();
            foreach (Control c in baseControl.Controls)
            {
                // データがバインドされたコントロールのみ取得
                if (c.DataBindings != null && c.DataBindings.Count > 0) controlList.Add(c);
                controlList.AddRange(GetBindedControls(c));
            }
            return controlList.ToArray();
        }

        /// <summary>
        /// フォーム読込みイベント。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void OptionForm_Load(object sender, EventArgs e)
        {
            // コントロールの変更をデータソースに反映しない
            foreach (Control c in BindedControls)
            {
                foreach (Binding bind in c.DataBindings)
                {
                    bind.DataSourceUpdateMode = DataSourceUpdateMode.Never;
                }
            }
            // データソースの値をコントロールに設定
            foreach (Control c in BindedControls)
            {
                foreach (Binding bind in c.DataBindings)
                {
                    bind.ReadValue();
                }
            }

            // クライアント領域が表示されるように最小サイズを調整
            //this.ClientSize = new Size(300, 300);
            //this.MinimumSize = new Size(this.Width, this.Height);
            //this.Size = new Size(this.Width, this.Height);
        }

        /// <summary>
        /// フォームを閉じた後のイベント。
        /// MediaPlayerオブジェクトを停止させる。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void OptionForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            mediaPlayer.controls.stop();
            mediaPlayer.close();
            mediaPlayer = null;
        }

        /// <summary>
        /// OKボタンクリックイベント。
        /// 設定を更新する。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void okButton_Click(object sender, EventArgs e)
        {
            // データソースの変更をコントロールに反映しない
            foreach (Control c in BindedControls)
            {
                foreach (Binding bind in c.DataBindings)
                {
                    bind.ControlUpdateMode = ControlUpdateMode.Never;
                }
            }
            // コントロールの値をデータソースに設定
            foreach (Control c in BindedControls)
            {
                foreach (Binding bind in c.DataBindings)
                {
                    bind.WriteValue();
                }
            }
            this.DialogResult = DialogResult.OK;
        }

        /// <summary>
        /// キャンセルボタンクリックイベント。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void cancelButton_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }
        
        /// <summary>
        /// サウンドファイル選択ボタンクリックイベント。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void informSoundSelectButton_Click(object sender, EventArgs e)
        {
            // ファイルを選択
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() != DialogResult.OK) return; // OK以外の場合は終了

            informSoundPathTextBox.Text = ofd.FileName;
        }

        /// <summary>
        /// サウンドファイル再生ボタンクリックイベント。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void informSoundPlayButton_Click(object sender, EventArgs e)
        {
            mediaPlayer.controls.stop();
            mediaPlayer.URL = informSoundPathTextBox.Text;
            mediaPlayer.settings.volume = 100;
            mediaPlayer.controls.play();
            
            // 再生可能な状態になるまで待機
            while (mediaPlayer.openState == WMPOpenState.wmposOpeningUnknownURL && mediaPlayer.playState == WMPPlayState.wmppsTransitioning)
            {
                System.Threading.Thread.Sleep(10);
                Application.DoEvents();
            }

            // 再生に失敗した場合
            if (mediaPlayer.openState != WMPOpenState.wmposMediaOpen || mediaPlayer.currentMedia.getItemInfo("MediaType") != "audio")
            {
                mediaPlayer.controls.stop();
                MessageBox.Show(
                    "メディアの再生に失敗しました。" + Environment.NewLine + "再生可能なファイルを選択してください。",
                    Application.ProductName,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// サウンドファイル停止ボタンクリックイベント。
        /// </summary>
        /// <param name="sender">イベント発生オブジェクト。</param>
        /// <param name="e">イベントパラメータ。</param>
        private void informSoundStopButton_Click(object sender, EventArgs e)
        {
            // 音声を停止
            mediaPlayer.controls.stop();
        }

    }
}
